/*
  Copyright (C) 2011, Kyungjoo Kim
  
  This file is part of UHM (Unassembled HyperMatrix) sparse direct solver.
  
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Also add information on how to contact you by electronic and paper mail.
  
  
  Kyungjoo Kim
  iamkyungjoo@gmail.com
*/
#ifndef UHM_INTERF_PETSC_HXX
#define UHM_INTERF_PETSC_HXX

namespace uhm {

  namespace interf {

    typedef class  Petsc_*         Petsc;

    // ----------------------------------------------------------------
    // ** Petsc
    class Petsc_ {
    private:
    protected:
      int datatype, show_n_rhs;

      int irank, nrank;

      Mat       A;

      // x approx solution, b rhs
      Vec       x,b,r;
      KSP       ksp;
    
      double    tol;
    
      int n_dof, n_rhs, n_nz;
      std::vector< int > ia, ja;
      std::vector< double > aa, xx, bb;

      bool created, spd;

      void _init(int datatype) {
        assert(datatype == UHM_REAL ||
               datatype == UHM_COMPLEX);
        this->datatype   = datatype;
        this->show_n_rhs = 0;
        this->created    = false;
        this->spd        = false;

        this->tol        = 1.0e-7;

        this->irank      = 0;
        this->nrank      = 1;
      }

    public:
      Petsc_()             { _init(UHM_REAL); }
      Petsc_(int datatype) { _init(datatype); }
      virtual ~Petsc_()    { }

      bool   export_matrix(Mesh m);

      void   disp() { this->disp(stdout); }
      void   disp( FILE *stream );

      bool   is_complex();
      bool   is_spd();

      void   set_spd(bool is_spd);
      void   set_tolerence(double tol);

      void   set_show_n_rhs(int show_n_rhs);

      int    create_sparse_matrix(Sparse sp, int is_sym);
      int    delete_sparse_matrix();

      int    get_n_dof();
      int    get_n_rhs();
      int    get_n_nonzero();
      double get_tolerence();

      bool   validate_sparse_matrix();

      int    init(int argc, char **argv);
      int    finalize();

      int    create_ksp();
      int    delete_ksp();
      int    set_pc_on_ksp(char *type);
      int    solve();
      int    check();

    };

    // ----------------------------------------------------------------
  }
}

#endif
